﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Castle.DynamicProxy;
using System.Reflection;
using CNKI.TPI.Web.Search.Model;

namespace CNKI.TPI.Web.Base
{
    public class LogInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            string inParamter = "";
            string outParamter = "";
            if (IsInfoLevelLog(invocation.TargetType.Name, invocation.Method.Name))
            {
                inParamter = BuildInParamter(invocation);
                LogOpr.Info(0, 0, invocation.TargetType.Name, invocation.Method.Name, inParamter, "", "");
            }
            else if (LogOpr.IsLogEnabled(CNKI.TPI.Web.Base.LogOpr.LogLevel.Debug))
            {
                inParamter = BuildInParamter(invocation);
                LogOpr.Debug(0, 0, invocation.TargetType.Name, invocation.Method.Name, inParamter, "", "");
            }

            if (LogOpr.IsLogEnabled(CNKI.TPI.Web.Base.LogOpr.LogLevel.Debug))
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();
                invocation.Proceed();
                sw.Stop();
                if (invocation.ReturnValue != null)
                {
                    outParamter = invocation.ReturnValue.ToString();
                } 
                LogOpr.Debug(1, sw.ElapsedMilliseconds, invocation.TargetType.Name, invocation.Method.Name, inParamter, outParamter, "");
            }
            else
            {
                invocation.Proceed();
                if (invocation.ReturnValue != null && invocation.ReturnValue.GetType().IsValueType)
                {
                    outParamter = invocation.ReturnValue.ToString();
                }
                if (IsInfoLevelLog(invocation.TargetType.Name, invocation.Method.Name) && !string.IsNullOrEmpty(outParamter))
                {
                    LogOpr.Info(1, 0, invocation.TargetType.Name, invocation.Method.Name, inParamter, outParamter, "");
                }
            }
        }

        /// <summary>
        /// 生成输入参数日志
        /// </summary>
        /// <param name="invocation"></param>
        /// <returns></returns>
        private string BuildInParamter(IInvocation invocation)
        {
            ParameterInfo[] paramList = invocation.Method.GetParameters();
            StringBuilder sb = new StringBuilder();
            object param = null;
            foreach (ParameterInfo item in paramList)
            {
                param = invocation.GetArgumentValue(item.Position);
                sb.Append(item.Name + "='" + ProcessParamValue(invocation.GetArgumentValue(item.Position)) + "'|");
            }
            if (sb.Length > 0)
            {
                sb.Remove(sb.Length - 1, 1);
            }
            return sb.ToString();
        }

        /// <summary>
        /// 是否输出为Info日志
        /// </summary>
        /// <param name="className"></param>
        /// <param name="funcName"></param>
        /// <returns></returns>
        private bool IsInfoLevelLog(string className, string funcName)
        {
            bool result = false;
            if ((("SearchService".Equals(className) || "UserDBDAO".Equals(className)) && ("SingleSearch".Equals(funcName) || "MultiSearch".Equals(funcName)))
                || ("UserService".Equals(className) && "ValidateUser".Equals(funcName))
                || ("SearchService".Equals(className) && ("InsertMetaData".Equals(funcName) || "UpdateMetaData".Equals(funcName)))
                || ("SubmitAdminService".Equals(className) && "UpdateMetaData".Equals(funcName)))
            {
                result = true;
            }
            //else if ("FileService".Equals(className) && ("GetFirstDigitalFileByType".Equals(funcName) || "GetDigitalFile".Equals(funcName)))
            //{
            //    result = true;
            //}
            return result;
        }

        private string ProcessParamValue(object content)
        {
            string result = "";
            try
            {
                if(content != null)
                {
                    if (content.GetType() == typeof(List<SearchQuery>))
                    {
                        IList<SearchQuery> paramList = (IList<SearchQuery>)content;
                        foreach (SearchQuery item in paramList)
                        {
                            if (!item.Key.Contains("SYS_FLD_"))
                            {
                                result += item.Text + ",";
                            }
                        }
                        if (result.Length > 0)
                        {
                            result = result.Substring(0, result.Length - 1);
                        }
                    }
                    else if (content.GetType() == typeof(List<SYS_CMS_DATABASE>))
                    {
                        IList<SYS_CMS_DATABASE> paramList = (IList<SYS_CMS_DATABASE>)content;
                        foreach (SYS_CMS_DATABASE item in paramList)
                        {
                            result += item.SysID + ",";
                        }
                        if (result.Length > 0)
                        {
                            result = result.Substring(0, result.Length - 1);
                        }
                    }
                    else
                    {
                        result = content.ToString();
                    }
                }
            }
            catch (Exception ex)
            {
                LogOpr.Error(ex.ToString());
            }
            return result;
        }
    }
}
